﻿using MinimumSpanningTree.Logic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MinimumSpanningTree
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 浏览
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBrowser_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "(*.txt)|*.txt";
            openFileDialog1.FileName = "";
            openFileDialog1.Title = "选择txt文件";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                txtPath.Text = openFileDialog1.FileName;
                SetValue(txtTip, "像素坐标文件为："+openFileDialog1.FileName);
            }
        }

        /// <summary>
        /// 运行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRun_Click(object sender, EventArgs e)
        {
            //1、找出所有点的匹配；
            string filename = txtPath.Text.Trim();
            if (Vaild())
            {
                string text = File.ReadAllText(filename);
                List<string> pointList = text.Split(' ').ToList();
                List<string> pointResults = new List<string>();
                foreach (var item in pointList)
                {
                    double point = 0.00000;
                    if (double.TryParse(item,out point))
                    {
                        pointResults.Add(item.Trim());
                    }
                }
                int index = 0;
                List<PointInfo> pointsList = new List<PointInfo>();
                while (index< pointResults.Count)
                {
                    PointInfo point = new PointInfo();
                    point.x =double.Parse(pointResults[index]) ;
                    point.y = double.Parse(pointResults[index+1]);
                    point.id = Guid.NewGuid().ToString().Replace("-", "").ToUpper();
                    index += 2;
                    pointsList.Add(point);
                }

                ///构造利用邻接表存储图的结构AdGraph
                AdGraph adgraphInfo = new AdGraph(pointsList.Count);
                for (int j = 0; j < pointsList.Count; j++)
                {
                    // adgraphInfo[j] = pointsList[j].id;
                    adgraphInfo[j] = pointsList[j].x + "-" + pointsList[j].y;
                }

                for (int i = 0; i < pointsList.Count; i++)
                {
                    string pointId = pointsList[i].x + "-" + pointsList[i].y;

                    foreach (var itemIn in pointsList)
                    {
                        //if (itemIn.id != pointsList[i].id)
                        string pointInId = itemIn.x + "-" + itemIn.y;
                        if (pointInId != pointId)
                        {
                            var xPoint = new PointInfo()
                            {
                                x = pointsList[i].x,
                                y = pointsList[i].y
                            };
                            var yPoint = new PointInfo()
                            {
                                x = itemIn.x,
                                y = itemIn.y
                            };
                            double distance = CalculatePixelDistance(xPoint, yPoint);
                            adgraphInfo.AddEdge(pointId, pointInId, distance);
                        }
                    }
                }

                //SpanTreeNode[] tree = adgraphInfo.MiniSpanTree(pointsList[0].id);
                SpanTreeNode[] tree = adgraphInfo.MiniSpanTree(pointsList[0].x + "-" + pointsList[0].y);
                double sum = 0;
                for (int i = 0; i < tree.Length; i++)
                {

                   string weight = tree[i].Weight.ToString("#0.0000");//点后面几个0就保留几位

                    string str = "(" + tree[i].ParentName + ","
                                    + tree[i].SelfName + ") Weight:"
                                    + weight;
                    Console.WriteLine(str);
                    SetValue(txtTip, str);
                    sum += tree[i].Weight;
                }
                SetValue(txtTip, "总的距离："+ sum.ToString("#0.0000"));


            }
        }


        /// <summary>
        /// 计算两个像素坐标距离[欧式距离（Euclidean Distance）]
        /// </summary>
        private double CalculatePixelDistance(PointInfo xPoint, PointInfo yPoint)
        {
            double distance =  Math.Pow(Math.Pow((xPoint.x - yPoint.x),2)+ Math.Pow((xPoint.y - yPoint.y), 2), 0.5);
            return distance;
        }


        /// <summary>
        /// 操作前校验
        /// </summary>
        /// <returns></returns>
        private bool Vaild()
        {
            if (string.IsNullOrEmpty(txtPath.Text.Trim()))
            {
                SetValue(txtTip, "请先选择文件路径！");
                return false;
            }

            if (!File.Exists(txtPath.Text.Trim()))
            {
                SetValue(txtTip, "路径不存在");
                return false;
            }

            if (!txtPath.Text.Trim().EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
            {
                SetValue(txtTip, "所选文件不是txt文件");
                return false;
            }

            return true;
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <param name="textBox"></param>
        /// <param name="msg"></param>
        private void SetValue(TextBox textBox, string msg)
        {
            BeginInvoke(new Action(() =>
            {
                textBox.Text += Environment.NewLine + msg;
            }));
        }

    }
}
